import { getSn, getUid, removeSn, removeToken } from '@/utils/auth';
import HttpRequest from './http'
import { addRequest, refreshToken } from "@/utils/refresh";
import { getToken } from '@/apis/account';
import sparkMd5 from 'spark-md5';
import type { Params, RequestConfig, ResponseType } from '@/types'

const WHITES = ['miniapp_wx_login', 'miniapp_login', 'init_cfg', 'get_code', 'login']
const modIgnore = ['account', 'advert', 'goods', 'system']



/**
 * 
 * @param {{url?: string, method?: 'GET'|'POST'|'PUT'|'DELETE', data: any}} options
 * @returns 
 */
export const request = (options: {data: Params}) => {
  const http = HttpRequest.getInstance();
  console.log('mod:', options.data?.mod);
  
  // if (!modIgnore.includes(options?.data?.mod)) {
  //   if (!getSn()) {
  //     uni.navigateTo({
  //       url: '/pages/login/login'
  //     })
  //     console.log('no sn');
  //     return Promise.reject('no sn')
  //   }
  // }
  http.interceptorRequest((config: RequestConfig) => {

    if (!WHITES.includes(config.data?.act)) {
      const _conf = {
        ...config.data
      }
      if(getSn()) {
        _conf.sn = getSn()
      }
      if(getUid()) {
        _conf.uid = getUid()
      }
      config.data = _conf
    }
    // 在这里可以添加token等

    if (!config.url) {
      config.url = ''
    }

    return config;
  }, (error: any) => {
    console.error('Request Error:', error);
    return error;
  });
  http.interceptorResponse((response: ResponseType, config: RequestConfig) => {
    // 对响应数据做点什么
    if (response.code === -997) {
      removeSn()
      removeToken()
      const pages = getCurrentPages()
      const currentPage = pages[pages.length - 1];
      if (currentPage.route !== 'pages/login/login') {
        console.log(-997);
        
        uni.navigateTo({
          url: '/pages/login/login'
        })
      }
      return response;
    }
    if (response.code === -998) {
      // 登录过期
      return new Promise((resolve, reject) => {
        addRequest(() => resolve(http.request(config)))
        refreshToken()
      })
    }
    if(response.code === -999 && !getSn()) {
      uni.showToast({
        title: '请先登录授权',
        icon: 'none',
      })
      const pages = getCurrentPages()
      const currentPage = pages[pages.length - 1];
      if (currentPage.route !== 'pages/login/login') {
        console.log('no sn');
        
        uni.navigateTo({
          url: '/pages/login/login'
        })
      }
      return response
    }
    if(response.code !== 1 && !response.ok) {
      return response
    }
    return response;
  }, (error:any) => {
    // 对响应错误做点什么
    uni.showToast({
      title: error?.msg || error?.message || '请求失败',
      icon: 'none',
    })
    return Promise.reject(error);
  });
  console.log(options.data);

  return http.request({
    url: import.meta.env.BASE_URL,
    method: 'GET',
    header: {'content-type': 'application/json'},
    ...options
  })
}

const qiniuUrl = 'https://up-z2.qiniup.com'
export const uploadFile = async (filePath: string) => {
  uni.showLoading()
  const { data } = await getToken()
  const md5 = await genHash(filePath)
  // 获取文件扩展名，如果match返回null则使用空字符串
  const fileExtension = filePath.match(/\.\w+$/)?.[0] || '';
  const key = md5 + fileExtension;
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: qiniuUrl,
      filePath,
      name: 'file',
      formData: {
        token:  data.token,
        key
      },
      success: (res) => {
        console.log(res);
        const data = JSON.parse(res.data)
        resolve(data.key)
      },
      complete: () => {
        uni.hideLoading()
      }
    })
  })
}

function genHash(filePath: string) {
  return new Promise((resolve, reject) => {
    uni.getFileSystemManager().readFile({
      filePath,
      success: (res) => {
        const spark = new sparkMd5.ArrayBuffer();
        if (res.data instanceof ArrayBuffer) {
          spark.append(res.data);
        } else {
          throw new Error('文件数据必须是 ArrayBuffer 类型');
        }
        const md5 = spark.end();
        resolve(md5)
      },
      fail: (err) => {
        reject(err)
      }
    })
  })
}